package lookie.app.ui.explorer;

import javax.swing.JComponent;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;

import lookie.swing.tree.navigation.Navigator;
import lookie.swing.tree.render.LabelProviderTreeCellRenderer;
import lookie.swing.tree.support.file.FileTreeNodeLabelProvider;

import org.springframework.richclient.application.support.AbstractView;
import org.springframework.richclient.command.ActionCommand;
import org.springframework.richclient.command.CommandGroup;
import org.springframework.richclient.util.PopupMenuMouseListener;

public class ExplorerView extends AbstractView {

	private JTree tree;

	private Navigator navigator;

	private JPopupMenu popupContextMenu;

	private RefreshCommand refreshCommand;

	private GoIntoCommand goIntoCommand;

	private GoUpCommand goUpCommand;

	private GoHomeCommand goHomeCommand;

	@Override
	protected JComponent createControl() {

		final FileSystemTreeNode root = new FileSystemTreeNode();

		final FileSystemTreeNodeProvider nodeProvider = new FileSystemTreeNodeProvider();
		final FileTreeNodeLabelProvider labelProvider = new FileTreeNodeLabelProvider();

		tree = new JTree();
		navigator = new FileSystemTreeNavigator(tree, root, nodeProvider);

		tree.setRootVisible(false);
		tree.setShowsRootHandles(true);

		LabelProviderTreeCellRenderer renderer = new LabelProviderTreeCellRenderer(
				labelProvider);
		tree.setCellRenderer(renderer);

		refreshCommand = new RefreshCommand();
		goIntoCommand = new GoIntoCommand();
		goUpCommand = new GoUpCommand();
		goHomeCommand = new GoHomeCommand();

//		tree.addTreeSelectionListener(new TreeSelectionListener() {
//			public void valueChanged(TreeSelectionEvent e) {
//				updateCommands();
//			}
//		});
		tree.addMouseListener(new PopupMenuMouseListener() {

			protected JPopupMenu getPopupMenu() {
				return getPopupContextMenu();
			}

		});

		JScrollPane scrollPane = getComponentFactory().createScrollPane(tree);

		return scrollPane;
	}

	private boolean isNothingSelected() {
		return tree.getSelectionCount() == 0;
	}

	private JPopupMenu getPopupContextMenu() {
		if (popupContextMenu == null) {
			CommandGroup group = getWindowCommandManager().createCommandGroup(
					"explorerViewPopupContextMenuCommandGroup",
					new Object[] { refreshCommand, "separator", goIntoCommand, "separator",
							goUpCommand, goHomeCommand });
			popupContextMenu = group.createPopupMenu();
		}
		updateCommands();
		return popupContextMenu;
	}

	private void updateCommands() {
		refreshCommand.setEnabled(!isNothingSelected());
		goIntoCommand.setEnabled(!isNothingSelected());

		goUpCommand.setEnabled(navigator.canGoUp());
	}

	private class GoIntoCommand extends ActionCommand {

		public GoIntoCommand() {
			super("goIntoCommand");
		}

		@Override
		protected void doExecuteCommand() {
			TreePath selectionPath = tree.getSelectionPath();
			if (selectionPath.getLastPathComponent() instanceof FileSystemTreeNode) {
				FileSystemTreeNode node = (FileSystemTreeNode) selectionPath
						.getLastPathComponent();
				navigator.goTo(node);
			}
		}

	}

	private class GoUpCommand extends ActionCommand {

		public GoUpCommand() {
			super("goUpCommand");
		}

		@Override
		protected void doExecuteCommand() {
			navigator.goUp();
		}

	}

	private class GoHomeCommand extends ActionCommand {

		public GoHomeCommand() {
			super("goHomeCommand");
		}

		@Override
		protected void doExecuteCommand() {
			navigator.goHome();
		}

	}

	private class RefreshCommand extends ActionCommand {

		public RefreshCommand() {
			super("refreshCommand");
		}

		@Override
		protected void doExecuteCommand() {
			TreePath selectionPath = tree.getSelectionPath();
			if (selectionPath.getLastPathComponent() instanceof FileSystemTreeNode) {
				FileSystemTreeNode node = (FileSystemTreeNode) selectionPath
						.getLastPathComponent();
				node.clear();
				update(node);
			}
		}

		private void update(FileSystemTreeNode node) {
			if (tree.getModel() instanceof DefaultTreeModel) {
				((DefaultTreeModel) tree.getModel()).nodeStructureChanged(node);
			}
		}

	}

}
